package com.wind.hallservice;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.provider.Settings;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.provider.CallLog;
import android.provider.CallLog.Calls;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;

import java.io.*;

/*
 * wuguohu@wind-mobi.com create
 */
public class HallService extends Service implements Handler.Callback {
	private static final String TAG = HallService.class.getSimpleName();
	private static final String SYS_HALL_STATUS = "system_hall_status";
	private static final int WHAT_STATUS_CHANGEDON = 100;
	private static final int WHAT_STATUS_CHANGEDOFF = 101;
	private static final int WHAT_STATUS_MMS = 102;
	private static final int WHAT_STATUS_CALLLOG = 103;
	
	public static final String KEYGUARD_HALL_ENABLED = "android.intent.action.KEYGUARD_HALL_ENABLED";
    public static final String KEYGUARD_HALL_DISABLED = "android.intent.action.KEYGUARD_HALL_DISABLED";
    public  static final String HALL_ACTIVE_PHONE_NUMBER = "android.hall.activephone.number";  
    public static final int HALL_OUT_GOING_CALL = 0X1019;
    
    private static final String CALL_NAME_REQUEST = "android.intent.action.CALL_NAME_REQUEST";
    private static final String CALL_NAME_RECEIVE = "android.intent.action.CALL_NAME_RECEIVE";
    private static final String NEW_OUTGOING_CALL_FAILED = "android.intent.action.NEW_OUTGOING_CALL_FAILED";

	private Context mContext;
	private Handler mHandler;
	private ContentObserver mHallContentObserver;
	private ContentObserver mMmsContentObserver;
	private ContentObserver mCallLogContentObserver;

	private HallWidget mHallView;
	private WindowManager mWindowManager;

	private boolean isHallViewShowing = false;

	private int mCallState = 0;
	private String mIncomingNumber;
	private String mCallerName;
	private boolean isDualCall = false;

	private static final Uri CONTENT_URI_SMS = Uri.parse("content://sms/");
	private static final Uri CONTENT_URI_MMS = Uri.parse("content://mms/inbox/");
	private int mMissedCall = 0;
	private int mMissedMms = 0;
	
	private BroadcastReceiver mOutgoingCallReceiver;
	private BroadcastReceiver mActivePhoneNumberReceiver;
	
	private static final int REQUEST_CALLER_MAX = 3;
	private int mRequestIndex = 0;

	@Override
	public IBinder onBind(Intent arg0) {
		return null;
	}

	@Override
	public void onCreate() {
		super.onCreate();

		mContext = this;
		mHandler = new Handler(this);

		ContentResolver cr = mContext.getContentResolver();
		mHallContentObserver = new HallContentObserver(mContext, mHandler);
		mMmsContentObserver = new MmsContentObserver(mHandler);
		mCallLogContentObserver = new CallLogContentObserver(mHandler);

		Uri hallConfigUri = Settings.System.getUriFor(SYS_HALL_STATUS);
		cr.registerContentObserver(hallConfigUri, true, mHallContentObserver);
		cr.registerContentObserver(CONTENT_URI_SMS, true, mMmsContentObserver);
		cr.registerContentObserver(CONTENT_URI_MMS, true, mMmsContentObserver);
		cr.registerContentObserver(CallLog.Calls.CONTENT_URI, true,
				mCallLogContentObserver);

		mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);

		TelephonyManager mTelephonyManager = (TelephonyManager) mContext
				.getSystemService(Context.TELEPHONY_SERVICE);
		mTelephonyManager.listen(new HallPhoneStatusListener(),
				PhoneStateListener.LISTEN_CALL_STATE);
		
		//receiver
		mOutgoingCallReceiver = new OutgoingCallReceiver();
		IntentFilter filter = new IntentFilter();
		filter.addAction(Intent.ACTION_NEW_OUTGOING_CALL);
		filter.addAction(Intent.ACTION_SCREEN_ON);
		filter.addAction(CALL_NAME_RECEIVE);
		filter.addAction(NEW_OUTGOING_CALL_FAILED);
		registerReceiver(mOutgoingCallReceiver, filter);
		//CaineZhu
		mActivePhoneNumberReceiver = new ActivePhoneNumberReceiver();
		IntentFilter filterNum = new IntentFilter();
		filterNum.addAction(HALL_ACTIVE_PHONE_NUMBER);
		registerReceiver(mActivePhoneNumberReceiver, filterNum);
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		initHallState();
		
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public void onDestroy() {
		super.onDestroy();

		//observer
		ContentResolver cr = mContext.getContentResolver();
		cr.unregisterContentObserver(mHallContentObserver);
		cr.unregisterContentObserver(mMmsContentObserver);
		cr.unregisterContentObserver(mCallLogContentObserver);
		
		//receiver
		if(mOutgoingCallReceiver != null){
			unregisterReceiver(mOutgoingCallReceiver);
		}
		
		if(mActivePhoneNumberReceiver !=null){
			unregisterReceiver(mActivePhoneNumberReceiver);
			}

		//view check
		checkRemoveHallView();
	}

	@Override
	public boolean handleMessage(Message msg) {
		switch (msg.what) {
		case WHAT_STATUS_CHANGEDON:
			checkAddHallView();
			makeKeygaurdEnabled();
			if (mHallView != null) {
				mHallView.setHallStatus(1);
			}
			break;
		case WHAT_STATUS_CHANGEDOFF:
			makeKeyguardDisabled();
			checkRemoveHallView();
			if (mHallView != null) {
				mHallView.setHallStatus(0);
			}
			break;
		case WHAT_STATUS_MMS:
			Log.d(TAG, "WHAT_STATUS_MMS, unread: " + mMissedMms);
			if (isHallViewShowing) {
				mHallView.setMissedInfo(mMissedCall, mMissedMms);
			}
			break;
		case WHAT_STATUS_CALLLOG:
			Log.d(TAG, "WHAT_STATUS_CALLLOG, unread: " + mMissedCall);
			if (isHallViewShowing) {
				mHallView.setMissedInfo(mMissedCall, mMissedMms);
			}
			break;
		default:
			break;
		}
		return false;
	}
	
	private void initHallState(){
		int state = HallState.getHallState();
		Log.d(TAG, "wuguohu, Hall State: " + state);
		if(state != 1){
			state = 0;
		}
		
		if(state == 1){
                         //hall on
                         writeHallSwitch(0);
                         mHandler.obtainMessage(WHAT_STATUS_CHANGEDON, state).sendToTarget();
                }

		Settings.System.putInt(mContext.getContentResolver(), SYS_HALL_STATUS, state);
	}

	private void checkAddHallView() {
		Log.d(TAG, "checkAddHallView");
		if (!isHallViewShowing) {
			mHallView = (HallWidget) LayoutInflater.from(mContext).inflate(
					R.layout.keyguard_hall_widget, null);
      mHallView.isDualCalling(isDualCall);      
			mHallView.setCallState(mCallState, mIncomingNumber);
			mHallView.onCallerNameReceived(mCallerName);
			mHallView.setMissedInfo(mMissedCall, mMissedMms);
			Log.d(TAG, "checkAddHallView, mCallState:" + mCallState
					+ ", mIncomingNumber:" + mIncomingNumber);
			WindowManager.LayoutParams params = new WindowManager.LayoutParams();
			params.type = WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
			params.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL
					| LayoutParams.FLAG_NOT_FOCUSABLE
					| LayoutParams.FLAG_LAYOUT_NO_LIMITS;
			params.width = LayoutParams.MATCH_PARENT;
			//params.height = LayoutParams.MATCH_PARENT;
			params.height = 1330;
			params.x = 0;
			params.y = -50;
			params.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
			mWindowManager.addView(mHallView, params);

			isHallViewShowing = true;
			
			// init missed info
			updateMissedCall();
			updateMissedMms();
		}

	}

	private void checkRemoveHallView() {
		Log.d(TAG, "checkRemoveHallView");
		if (isHallViewShowing) {
			try {
				mWindowManager.removeView(mHallView);
				isHallViewShowing = false;
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

	}

	private void updateMissedCall() {
		mHandler.post(new Runnable() {

			@Override
			public void run() {
				mMissedCall = getMissedCallCount();
				mHandler.obtainMessage(WHAT_STATUS_CALLLOG).sendToTarget();
			}

		});
	}

	private void updateMissedMms() {
		mHandler.post(new Runnable() {

			@Override
			public void run() {
				mMissedMms = getMissedMmsCount();
				mHandler.obtainMessage(WHAT_STATUS_MMS).sendToTarget();
			}

		});
	}

	private int getMissedCallCount() {
		int count = 0;

		try {
			Cursor c = mContext.getContentResolver().query(
					CallLog.Calls.CONTENT_URI, new String[] { Calls.TYPE },
					Calls.TYPE + "=? and " + Calls.NEW + "=?",
					new String[] { Calls.MISSED_TYPE + "", "1" }, null);
			if (c != null) {
				count = c.getCount();
				c.close();
			}
		} catch (Exception e) {
		}

		return count;
	}

	private int getMissedMmsCount() {
		int count = 0;

		Cursor c = null;
		try {
			c = mContext.getContentResolver().query(CONTENT_URI_SMS, null,
					"type = 1 and read = 0", null, null);
			if (c != null) {
				count += c.getCount();
				c.close();
			}
			c = mContext.getContentResolver().query(CONTENT_URI_MMS, null,
					"read = 0", null, null);
			if (c != null) {
				count += c.getCount();
				c.close();
			}
		} catch (Exception e) {
		}
		return count;
	}
	
	private void makeKeyguardDisabled(){
	    
		Intent intent = new Intent(KEYGUARD_HALL_DISABLED);
		mContext.sendBroadcast(intent);
	}
	
	private void makeKeygaurdEnabled(){
		Intent intent = new Intent(KEYGUARD_HALL_ENABLED);
		mContext.sendBroadcast(intent);
	}
	
	private void requestCallerName() {
		Log.d(TAG, "requestCallerName start");
                mCallerName = "";
		mRequestIndex = 0;
		mHandler.postDelayed(new RequestCallerNameThread(), 500);
	}
	
	private class RequestCallerNameThread implements Runnable{

		@Override
		public void run() {
			if(mRequestIndex < REQUEST_CALLER_MAX && (mCallerName == null || mCallerName.length() == 0)){
				Log.d("wuguohu", "requestCallerName, mRequestIndex: " + mRequestIndex);
				Intent intent = new Intent(CALL_NAME_REQUEST);
				mContext.sendBroadcast(intent);
				
				mRequestIndex++;
				mHandler.postDelayed(new RequestCallerNameThread(), 1000);
			}
			
		}
		
	}

	class HallPhoneStatusListener extends PhoneStateListener {

		@Override
		public void onCallStateChanged(int state, String incomingNumber) {
			super.onCallStateChanged(state, incomingNumber);
			Log.d(TAG, "onCallStateChanged, state:" + state
					+ ", incomingNumber:" + incomingNumber);

			mCallState = state;
			if (state == TelephonyManager.CALL_STATE_RINGING) {
				mIncomingNumber = incomingNumber;
				requestCallerName();
			}else if(state == TelephonyManager.CALL_STATE_IDLE){
				mIncomingNumber = "";
				mCallerName = "";
			}

			if (isHallViewShowing) {
				mHallView.onCallStateChanged(mCallState, mIncomingNumber);
                                if(state != TelephonyManager.CALL_STATE_IDLE){
                                    //HallState.setHallCfg(1);
                                }else{
                                    //HallState.setHallCfg(0);
                                }
			}
		}

	}

	private class HallContentObserver extends ContentObserver {
		private Context mContext;
		private Handler mHandler;

		public HallContentObserver(Context context, Handler handler) {
			super(handler);
			mContext = context;
			mHandler = handler;
		}

		@Override
		public void onChange(boolean selfChange) {
			super.onChange(selfChange);

			int status = Settings.System.getInt(mContext.getContentResolver(),
					SYS_HALL_STATUS, 0);
			Log.e(TAG, "wuguohu, HallContentObserver onChange , status: " + status);
                        if(mCallState != TelephonyManager.CALL_STATE_IDLE){
                             //HallState.setHallCfg(status);
                        }

			if (status == 1) {
                                        //hall on
                                        writeHallSwitch(0);
                                        mHandler.obtainMessage(WHAT_STATUS_CHANGEDON, status).sendToTarget();
                                } else {
                                        //hall off
                                        writeHallSwitch(1);
                                        mHandler.obtainMessage(WHAT_STATUS_CHANGEDOFF, status).sendToTarget();

                                }


		}

	}

	private class MmsContentObserver extends ContentObserver {

		public MmsContentObserver(Handler handler) {
			super(handler);
		}

		@Override
		public void onChange(boolean selfChange) {
			super.onChange(selfChange);
			Log.d(TAG, "MmsContentObserver onChange");
			updateMissedMms();
		}

	}

	private class CallLogContentObserver extends ContentObserver {

		public CallLogContentObserver(Handler handler) {
			super(handler);
		}

		@Override
		public void onChange(boolean selfChange) {
			super.onChange(selfChange);
			Log.d(TAG, "CallLogContentObserver onChange");
			updateMissedCall();
		}

	}
	
	private class OutgoingCallReceiver extends BroadcastReceiver{

		@Override
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			if (Intent.ACTION_NEW_OUTGOING_CALL.equals(action)) {
				String outgoingNumber = intent
						.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
				Log.d(TAG, "ACTION_NEW_OUTGOING_CALL, outging phone number:" + outgoingNumber);
				mCallState = HALL_OUT_GOING_CALL;
			 // mCallState = TelephonyManager.CALL_STATE_RINGING;
				Log.d(TAG, "ACTION_NEW_OUTGOING_CALL, onCallStateChanged state = " + mCallState);
				mIncomingNumber = outgoingNumber;
				requestCallerName();

				if (isHallViewShowing) {
					mHallView.onCallStateChanged(mCallState, mIncomingNumber);
				}
			} else if (NEW_OUTGOING_CALL_FAILED.equals(action)){
				String outgoingNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
                                Log.d(TAG, "NEW_OUTGOING_CALL_FAILED, outging phone number:" + outgoingNumber);
				if(outgoingNumber != null && outgoingNumber.equals(mIncomingNumber)){
					mCallState = TelephonyManager.CALL_STATE_IDLE;
					Log.d(TAG, "NEW_OUTGOING_CALL_FAILED, onCallStateChanged state = " + mCallState);
					if (isHallViewShowing) {
                                        	mHallView.onCallStateChanged(mCallState, mIncomingNumber);
                                	}
				}
			} else if (Intent.ACTION_SCREEN_ON.equals(action)) {
				if (mCallState != TelephonyManager.CALL_STATE_IDLE
						&& isHallViewShowing) {
					//HallState.setHallCfg(1);
				}
			} else if (CALL_NAME_RECEIVE.equals(action)) {
				mCallerName = intent.getStringExtra("callername");
				Log.d("wuguohu", "callername: " + mCallerName);
				if (isHallViewShowing && mHallView != null) {
					mHallView.onCallerNameReceived(mCallerName);
				}
				
			}
		}
		
	}
	
	//CaineZhu
	private class ActivePhoneNumberReceiver extends BroadcastReceiver{

		@Override
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			Log.d("CaineZhu", "CaineZhu action:" + action);
			if (HALL_ACTIVE_PHONE_NUMBER.equals(action)) {
				String activePhoneNumber = intent.getExtras().getString("activephonenumber");
				String callStateForhall = intent.getExtras().getString("callStateForhall");
				isDualCall = intent.getExtras().getBoolean("isdualcall");
				Log.d("CaineZhu", "CaineZhu activePhoneNumber:" + activePhoneNumber +" callStateForhall ::: "+callStateForhall+"  isDualCall ::: "+isDualCall);
			
				mIncomingNumber = activePhoneNumber;
				requestCallerName();

				if (isHallViewShowing) {
				/**	 String callStateForhall = "NULL";
        if(InCallState.NO_CALLS == state){
        	callStateForhall = "IDLE";
        }else if(InCallState.INCOMING == state){
        	callStateForhall = "INCOMING";
        }else if(InCallState.INCALL == state){
          callStateForhall = "INCALL";
        }else if(InCallState.OUTGOING == state){
          callStateForhall = "OUTGOING";
        }else{
    	      callStateForhall = "SMWY";
    	  }**/
    	  if(callStateForhall.equals("IDLE")){
    	  	mCallState =TelephonyManager.CALL_STATE_IDLE;
    	  }else if(callStateForhall.equals("INCOMING")){
    	    mCallState =TelephonyManager.CALL_STATE_RINGING;
    	  }else if(callStateForhall.equals("INCALL")){
    	  	mCallState =TelephonyManager.CALL_STATE_OFFHOOK;
    	  }else if(callStateForhall.equals("OUTGOING")){
    	  	mCallState = HALL_OUT_GOING_CALL;
			//	mCallState = 0X010;
    	  }else{
    	  	mCallState =TelephonyManager.CALL_STATE_IDLE;
    	  	Log.e("CaineZhu","CaineZhu ELSE WFT?????");
    	  }
    	    mHallView.isDualCalling(isDualCall);
					mHallView.onCallStateChanged(mCallState, mIncomingNumber);
					//mHallView.setActivePhoneNumber(mIncomingNumber);
				
				}
			}
		}
		
	}
  
	private void writeHallSwitch(int cfg){
		File file = new File("/proc/gt9xx_hall_switch");
		FileWriter fw = null;
		try{
		fw = new FileWriter(file, false);
		fw.write(cfg + "");
		fw.close();
		}catch(Exception e){
		}

	}

}
